package com.lowca.news.web.controller.front;

import java.io.IOException;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;

import org.apache.commons.beanutils.PropertyUtils;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.lowca.news.constant.Constants;
import com.lowca.news.entity.User;
import com.lowca.news.exception.account.AutoLoginException;
import com.lowca.news.exception.account.EmailExistException;
import com.lowca.news.exception.account.UsernameExistException;
import com.lowca.news.service.RoleService;
import com.lowca.news.service.UserService;
import com.lowca.news.util.Captchas;
import com.lowca.news.util.Exceptions;
import com.lowca.news.web.formbean.RegisterForm;

@Controller
public class AccountController {

	@Resource
	private UserService userService;

	@Resource
	private RoleService roleService;

	@RequestMapping(value = "/login.do", method = RequestMethod.GET)
	public String login(HttpServletRequest request) throws ServletException,
			IOException {
		Boolean hasAnyRoles = roleService.hasAnyRoles(Constants.getRoleNames());
		if (hasAnyRoles) {
			return "redirect:/index.do";
		} else {
			// 清空错误消息
			String error = request.getParameter("error");
			if (!"true".equals(error)) {
				HttpSession session = request.getSession();
				session.removeAttribute("SPRING_SECURITY_LAST_EXCEPTION");
			}
			return "/login";
		}
	}

	@RequestMapping(value = "/register.do", method = RequestMethod.GET)
	public String register(HttpServletRequest request, Map<String, Object> model)
			throws ServletException, IOException {
		Boolean hasAnyRoles = roleService.hasAnyRoles(Constants.getRoleNames());
		if (hasAnyRoles) {
			return "redirect:/index.do";
		} else {
			RegisterForm form = new RegisterForm();
			form.setAgreement(true);
			model.put("user", form);
			return "/register";
		}
	}

	@RequestMapping(value = "/register.do", method = RequestMethod.POST)
	public ModelAndView registerSubmit(HttpServletRequest request,
			@ModelAttribute("user") @Valid RegisterForm user,
			BindingResult result) throws ServletException, IOException {
		if (result.hasErrors()) {
			return new ModelAndView("/register");
		}
		// 查看验证码是否正确
		if (!Captchas.check(request, user.getCaptcha())) {
			result.rejectValue("captcha", null, "验证码错误");
			return new ModelAndView("/register");
		}
		// 执行注册逻辑
		User regUser = new User();
		try {
			PropertyUtils.copyProperties(regUser, user);
		} catch (Exception e) {
			Exceptions.unchecked(e);
		}
		regUser.setRegisterIp(request.getRemoteAddr());
		// 出现重复注册异常，跳回到注册视图
		try {
			userService.createUser(regUser);
		} catch (UsernameExistException e) {
			result.rejectValue("username", null, "用户名已经被注册过了");
			return new ModelAndView("/register");
		} catch (EmailExistException e) {
			result.rejectValue("email", null, "邮箱已经被注册过了");
			return new ModelAndView("/register");
		}
		// 自动登录异常则重定向到登录视图去
		try {
			userService.autoLogin(user.getUsername(), user.getPassword(),
					request);
		} catch (AutoLoginException e) {
			return new ModelAndView("redirect:/login.do");
		}
		return new ModelAndView("redirect:/index.do");
	}

	@RequestMapping(value = "/exist-username.do", method = RequestMethod.GET)
	@ResponseBody
	public String existUsername(HttpServletRequest request,
			HttpServletResponse response,
			@RequestParam(value = "username", required = true) String username)
			throws ServletException, IOException {
		return String.valueOf(!userService.existUserByUsername(username));
	}

	@RequestMapping(value = "/exist-email.do", method = RequestMethod.GET)
	@ResponseBody
	public String existEmail(HttpServletRequest request,
			HttpServletResponse response,
			@RequestParam(value = "email", required = true) String email)
			throws ServletException, IOException {
		return String.valueOf(!userService.existUserByEmail(email));
	}

	@RequestMapping(value = "/validate-captcha.do", method = RequestMethod.GET)
	@ResponseBody
	public String validateCaptcha(HttpServletRequest request,
			HttpServletResponse response,
			@RequestParam(value = "captcha", required = true) String captcha)
			throws ServletException, IOException {
		return String.valueOf(Captchas.look(request, captcha));
	}

}
